use crate::user::{User, dao::UserDAO};
use axum::{
    extract::{Path, State},
    http::StatusCode,
    response::Json,
};
use std::sync::Arc;
use sqlx::sqlite::SqlitePool;

// 数据库连接池类型
type Db = Arc<SqlitePool>;

// 获取所有用户
pub async fn list_users(State(db): State<Db>) -> Result<Json<Vec<User>>, (StatusCode, String)> {
    let user_dao = UserDAO::new(db);
    match user_dao.list_users().await {
        Ok(users) => Ok(Json(users)),
        Err(e) => Err((StatusCode::INTERNAL_SERVER_ERROR, e.to_string())),
    }
}

// 创建新用户
pub async fn create_user(State(db): State<Db>, Json(user): Json<User>) -> Result<Json<User>, (StatusCode, String)> {
    let user_dao = UserDAO::new(db);
    match user_dao.create_user(&user).await {
        Ok(id) => {
            let new_user = User {
                id: Some(id),
                name: user.name,
                sex: user.sex,
            };
            Ok(Json(new_user))
        },
        Err(e) => Err((StatusCode::INTERNAL_SERVER_ERROR, e.to_string())),
    }
}

// 根据ID获取用户
pub async fn get_user(State(db): State<Db>, Path(id): Path<i32>) -> Result<Json<User>, (StatusCode, String)> {
    let user_dao = UserDAO::new(db);
    match user_dao.get_user(id).await {
        Ok(Some(user)) => Ok(Json(user)),
        Ok(None) => Err((StatusCode::NOT_FOUND, "User not found".to_string())),
        Err(e) => Err((StatusCode::INTERNAL_SERVER_ERROR, e.to_string())),
    }
}

// 更新用户
pub async fn update_user(State(db): State<Db>, Path(id): Path<i32>, Json(user): Json<User>) -> Result<Json<User>, (StatusCode, String)> {
    let user_dao = UserDAO::new(db);
    match user_dao.update_user(id, &user).await {
        Ok(true) => {
            let updated_user = User {
                id: Some(id),
                name: user.name,
                sex: user.sex,
            };
            Ok(Json(updated_user))
        },
        Ok(false) => Err((StatusCode::NOT_FOUND, "User not found".to_string())),
        Err(e) => Err((StatusCode::INTERNAL_SERVER_ERROR, e.to_string())),
    }
}

// 删除用户
pub async fn delete_user(State(db): State<Db>, Path(id): Path<i32>) -> Result<StatusCode, (StatusCode, String)> {
    let user_dao = UserDAO::new(db);
    match user_dao.delete_user(id).await {
        Ok(true) => Ok(StatusCode::NO_CONTENT),
        Ok(false) => Err((StatusCode::NOT_FOUND, "User not found".to_string())),
        Err(e) => Err((StatusCode::INTERNAL_SERVER_ERROR, e.to_string())),
    }
}